package com.gfxy.modules.classtime.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gfxy.modules.classtime.vo.ClasstimeScorePage;
import com.gfxy.modules.common.entity.TotalScore;
import com.gfxy.modules.common.service.ITotalScoreService;
import com.gfxy.modules.config.entity.ConfigBaseclasstime;
import com.gfxy.modules.config.service.IConfigBaseclasstimeService;
import com.gfxy.modules.classtime.entity.ClasstimeScore;
import com.gfxy.modules.classtime.mapper.ClasstimeScoreMapper;
import com.gfxy.modules.classtime.service.IClasstimeScoreService;
import com.gfxy.modules.system.service.ISysUserDepartService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.*;

/**
 * @Description: 课时分数表
 * @Author: jeecg-boot
 * @Date:   2021-08-30
 * @Version: V1.0
 */
@Service
@Slf4j
public class ClasstimeScoreServiceImpl extends ServiceImpl<ClasstimeScoreMapper, ClasstimeScore> implements IClasstimeScoreService {

    @Autowired
    private ClasstimeScoreMapper classtimeScoreMapper;

    @Autowired
    private IConfigBaseclasstimeService baseclasstimeService;

    @Autowired
    private ISysUserDepartService sysUserDepartService;

    @Autowired
    private ITotalScoreService totalScoreService;

    @Override
    public void computeClasstimePoints(String year) {

        Map<Integer,ConfigBaseclasstime> configBaseclasstimes = this.getConfigBaseclasstime();

        List<Map> classTimeScoresList = classtimeScoreMapper.getClasstimeScoreByYear(year);

        List<ClasstimeScore> classtimeScores = new ArrayList<>();
        List<TotalScore> totalScores = new ArrayList<>();


        for (Map classTimeScoreItem : classTimeScoresList) {
            ClasstimeScore classtimeScore = this.createClasstimeScore( classTimeScoreItem);
            classtimeScores.add(classtimeScore);
            totalScores.add(this.computeClasstimeOne(configBaseclasstimes, classTimeScoreItem, classtimeScore));
        }

        // 删除
        LambdaQueryWrapper<ClasstimeScore> query = new LambdaQueryWrapper<ClasstimeScore>();
        query.eq(ClasstimeScore::getDate,year);
        this.remove(query);
        this.saveBatch(classtimeScores);

        LambdaQueryWrapper<TotalScore> deleteQuery = new LambdaQueryWrapper<TotalScore>();
        deleteQuery.eq(TotalScore::getDate,year).eq(TotalScore::getProjectId,1).eq(TotalScore::getClassificationId,"1697188915323146242");
        totalScoreService.remove(deleteQuery);
        totalScoreService.saveBatch(totalScores,1000);
    }

    @Override
    public void computeClasstimePointsForOneTeacher(String year, String teacherId){
        Map<Integer,ConfigBaseclasstime> configBaseclasstimes = this.getConfigBaseclasstime();
        Map classTimeScoreItem = classtimeScoreMapper.getClasstimeScoreByYearAndTeacher(year, teacherId);

        if (classTimeScoreItem != null && !classTimeScoreItem.isEmpty()){
            //总课时
            ClasstimeScore classtimeScore = this.createClasstimeScore( classTimeScoreItem);
            LambdaQueryWrapper<ClasstimeScore> query = new LambdaQueryWrapper<ClasstimeScore>();
            query.eq(ClasstimeScore::getDate,year);
            query.eq(ClasstimeScore::getTeacherCode, teacherId);
            this.remove(query);
            this.save(classtimeScore);
//        计算积分
            TotalScore totalScore = this.computeClasstimeOne(configBaseclasstimes, classTimeScoreItem, classtimeScore);
            LambdaQueryWrapper<TotalScore> deleteQuery = new LambdaQueryWrapper<TotalScore>();
            deleteQuery.eq(TotalScore::getDate,year).eq(TotalScore::getProjectId,1)
                    .eq(TotalScore::getClassificationId,"1697188915323146242")
                    .eq(TotalScore::getTeacherId, teacherId);
            totalScoreService.remove(deleteQuery);
            totalScoreService.save(totalScore);
        }

    }


    public TotalScore computeClasstimeOne(Map<Integer,ConfigBaseclasstime> configBaseclasstimes , Map classTimeScoreItem, ClasstimeScore classtimeScore){

        double score = this.computeClasstimeScore(configBaseclasstimes, classTimeScoreItem);
        TotalScore totalScore = new TotalScore();
        totalScore.setOrgCode(classtimeScore.getOrgCode());
        totalScore.setDate(classtimeScore.getDate());
        totalScore.setScore(score);
        totalScore.setTeacherId(classtimeScore.getTeacherCode());
        totalScore.setProjectId(1);
        totalScore.setClassificationId("1697188915323146242");
        return totalScore;
    }


    @Override
    public IPage<ClasstimeScorePage> listByYearAndDep(Page<ClasstimeScorePage> page, String year, String depCode) {
        return classtimeScoreMapper.getClasstimeScoreListByYearAndDep(page,year,depCode);

    }

    @Override
    public ClasstimeScore queryByDateAndTeacherId(String date, String teacherId) {
        return classtimeScoreMapper.getClasstimeScoreListByYearAndUsername(date,teacherId);
    }


    private ClasstimeScore createClasstimeScore(Map classTimeScoreItem){
        ClasstimeScore classtimeScore = new ClasstimeScore();
        classtimeScore.setDate(classTimeScoreItem.get("date").toString());
        classtimeScore.setTeacherCode(classTimeScoreItem.get("teacher_code").toString());

        classtimeScore.setOrgCode(classTimeScoreItem.get("dep_id").toString());


        classtimeScore.setLecture(Double.parseDouble(classTimeScoreItem.get("lecture").toString()));
        classtimeScore.setCourseDesign(Double.parseDouble(classTimeScoreItem.get("course_design").toString()));
        classtimeScore.setPractical(Double.parseDouble(classTimeScoreItem.get("practical").toString()));

        classtimeScore.setGraduateTutorial(Double.parseDouble(classTimeScoreItem.get("graduate_tutorial").toString()));
        classtimeScore.setGraduateDefense(Double.parseDouble(classTimeScoreItem.get("graduate_defense").toString()));
        classtimeScore.setExamination(Double.parseDouble(classTimeScoreItem.get("examination").toString()));

        classtimeScore.setInternship(Double.parseDouble(classTimeScoreItem.get("internship").toString()));
        classtimeScore.setPracticalTutorial(Double.parseDouble(classTimeScoreItem.get("practical_tutorial").toString()));
        classtimeScore.setOther(Double.parseDouble(classTimeScoreItem.get("other").toString()));

        double totalClassTime = Double.parseDouble(classTimeScoreItem.get("total_classtime").toString());
        classtimeScore.setTotalClasstime(totalClassTime);
        return classtimeScore;
    }


    @NotNull
    private double computeClasstimeScore(Map<Integer, ConfigBaseclasstime> configBaseclasstimes, Map classTimeScoreItem) {
        log.debug("开始计算教师[{}]的课时积分", classTimeScoreItem.get("teacher_code").toString());

        double totalClassTime = Double.parseDouble(classTimeScoreItem.get("total_classtime").toString());

        int titleLevel = Integer.parseInt(classTimeScoreItem.get("title_level").toString());
        int positionLevel = Integer.parseInt(classTimeScoreItem.get("position_level").toString());


        log.debug("titleLeavel is {}" , titleLevel);

        ConfigBaseclasstime configBaseclasstime = configBaseclasstimes.get(titleLevel);

        double baseClasstime = Double.parseDouble(configBaseclasstime.getBaseClasstime());
        double basePoints = Double.parseDouble(configBaseclasstime.getBasePoints());
        log.debug("基础课时为：[{}]， 基础积分为：[{}]", baseClasstime, basePoints);
        baseClasstime = this.getPositionConverte(baseClasstime, positionLevel);
        log.debug("减免后的基础课时为: [{}]", baseClasstime);
        // todo 科研
//            baseClasstime = this.getConverte(baseClasstime)


        if(totalClassTime>900){
            log.debug("课时总量超过900课时，按900课时计算");
            totalClassTime = 900;
        }

        double temp = totalClassTime - baseClasstime;
        log.debug("总课时为[{}], 基础课时为[{}], 相差[{}]", totalClassTime, baseClasstime, temp);
        double points = 0.0;

        if(temp >= 0){
            points = temp/20 + basePoints;
            log.debug("满足基本积分,重新计算积分为：[{}]" , points);
        } else {
            points = temp/10 + basePoints;
            log.debug("未满足基本积分,重新计算积分为：[{}]" , points);
        }

        return Math.round( points * 100 ) / 100.0;

    }

    private double getPositionConverte(double baseClasstime, int positionLevel) {
        log.debug("开始计算减免课时， 基础课时为[{}]， 职务为[{}]", baseClasstime, positionLevel);
        if(positionLevel == 7){
            return baseClasstime * 0.8;
        } else
//            if(positionLevel ==3){
//            return baseClasstime * 0.85;
//        } else
        {
            return baseClasstime * 1;
        }
    }


    private Map<Integer,ConfigBaseclasstime> getConfigBaseclasstime(){
        Map<Integer,ConfigBaseclasstime> result = new HashMap<>();
        List<ConfigBaseclasstime> configBaseclasstimes = baseclasstimeService.list();
        for (ConfigBaseclasstime configBaseclasstime : configBaseclasstimes) {
            result.put(configBaseclasstime.getTitleLeave(), configBaseclasstime);
        }
        return result;
    }
}
